﻿using System.Collections.ObjectModel;
using System.Windows.Media;
using System.Windows.Threading;
using LiveChartsCore;
using LiveChartsCore.Defaults;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using LiveChartsCore.Themes;
using SkiaSharp;
using Wpf.Ui;
using Wpf.Ui.Appearance;

namespace FileTransferDesktop.ViewModels.Controls
{
    public partial class SpeedChartViewModel : ObservableObject, IDisposable
    {
        private const int Capacity = 40;
        private long _lastWrittenBytes;
        private DateTime _lastMeasureTime = DateTime.Now;

        private readonly ObservableCollection<ObservableValue> _lineValues;
        private readonly ObservableCollection<ObservableValue> _barValues;

        private DispatcherTimer? _updateTimer;
        private DispatcherTimer? _decayTimer;
        private int _decayTotalTicks;
        private int _decayTicksLeft;
        private readonly double _lastSpeed; // 数据缓冲队列，确保均匀左移
        private readonly Queue<(double speedValue, double blockValue)> _dataBuffer = new();
        private readonly Lock _bufferLock = new();
        private (double speedValue, double blockValue) _currentData = (0, 0);
        private (double speedValue, double blockValue) _previousData = (0, 0);

        [ObservableProperty]
        private ISeries[] _series;

        [ObservableProperty]
        private Axis[] _xAxes;

        [ObservableProperty]
        private Axis[] _yAxes;

        [ObservableProperty]
        private string _transferLabel = "暂无传输";

        [ObservableProperty]
        private string _transferProgress = "";

        [ObservableProperty]
        private double _progressPercentage = 0.0;

        [ObservableProperty]
        private LiveChartsCore.Measure.Margin _margin;

        [ObservableProperty]
        private SolidColorPaint _legendTextPaint;

        public SpeedChartViewModel()
        {
            _lineValues = [];
            _barValues = [];

            // 初始化空数据点，确保图表从开始就有完整的容量
            for (var i = 0; i < Capacity; i++)
            {
                _lineValues.Add(new ObservableValue());
                _barValues.Add(new ObservableValue());
            }
            Series =
            [
                new LineSeries<ObservableValue>
                {
                    Values = _lineValues,
                    GeometrySize = 0,
                    Name = "速率",
                    Stroke = new SolidColorPaint(SKColors.LimeGreen, 2),
                    Fill = null,
                    ScalesYAt = 0,
                    EasingFunction = EasingFunctions.ElasticInOut,
                    LineSmoothness = 0.2, // 适度平滑曲线
                    AnimationsSpeed = TimeSpan.FromMilliseconds(100), // 与更新频率匹配
                },
                new ColumnSeries<ObservableValue>
                {
                    Name = "块大小",
                    Values = _barValues,
                    Stroke = null,
                    Fill = new SolidColorPaint(SKColors.DodgerBlue.WithAlpha(128)),
                    ScalesYAt = 1,
                    AnimationsSpeed = TimeSpan.FromMilliseconds(500), // 与更新频率匹配
                },
            ];
            YAxes =
            [
                new Axis
                {
                    IsVisible = false,
                    MinLimit = 0,
                    DrawTicksPath = true,
                },
                new Axis { IsVisible = false, MinLimit = 0 },
            ];

            XAxes =
            [
                new Axis
                {
                    MinLimit = 0,
                    MaxLimit = Capacity - 1,
                    IsVisible = false,
                },
            ];
            var auto = LiveChartsCore.Measure.Margin.Auto;
            Margin = new LiveChartsCore.Measure.Margin(auto, auto, auto, auto);

            UpdateLegendTextPaint();
            // 订阅主题变更事件
            ApplicationThemeManager.Changed += OnApplicationThemeChanged;
            // 启动定时器，确保图表持续更新（像任务管理器一样）
            StartUpdateTimer();
        }

        private void OnApplicationThemeChanged(
            ApplicationTheme currentApplicationTheme,
            Color systemAccent
        )
        {
            UpdateLegendTextPaint();
        }

        private int _activeCount = 0;

        private void UpdateLegendTextPaint()
        {
            var color = (Color)Application.Current.Resources["TextFillColorPrimary"];
            LegendTextPaint = new SolidColorPaint(new SKColor(color.R, color.G, color.B, color.A));
        }

        private void StartUpdateTimer()
        {
            _updateTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(500) };
            _updateTimer.Tick += (s, e) =>
            {
                if (_activeCount-- < 0)
                    return;
                (double speedValue, double blockValue) dataToAdd;

                lock (_bufferLock)
                {
                    if (_dataBuffer.Count > 0)
                    {
                        // 有新数据，使用缓冲区的数据
                        _previousData = _currentData;
                        dataToAdd = _dataBuffer.Dequeue();
                        _currentData = dataToAdd;
                    }
                    else if (_isTransferring)
                    {
                        // 正在传输但没有新数据，使用当前数据与前一个数据的插值保持连续性
                        var alpha = 0.8; // 插值系数，让过渡更平滑
                        dataToAdd = (
                            _currentData.speedValue * alpha
                                + _previousData.speedValue * (1 - alpha),
                            _currentData.blockValue * alpha + _previousData.blockValue * (1 - alpha)
                        );
                    }
                    else
                    {
                        // 没有传输，逐渐衰减到零值
                        var alpha = 0.9; // 衰减系数
                        dataToAdd = (
                            _currentData.speedValue * alpha,
                            _currentData.blockValue * alpha
                        );
                        _currentData = dataToAdd;

                        // 如果值已经很小，直接设为0
                        if (dataToAdd.speedValue < 0.1 && dataToAdd.blockValue < 0.1)
                        {
                            dataToAdd = (0, 0);
                            _currentData = (0, 0);
                            _previousData = (0, 0);
                        }
                    }
                }

                AddPointInternal(dataToAdd.speedValue, dataToAdd.blockValue);
            };
            _updateTimer.Start();
        }

        private bool _isTransferring = false;

        public void UpdateProgress(long writtenBytes)
        {
            _activeCount = 3;
            var now = DateTime.Now;
            var timeSpan = now - _lastMeasureTime;
            if (timeSpan.TotalMilliseconds < 100)
                return;

            var deltaBytes = writtenBytes - _lastWrittenBytes;

            // 防止负值和异常情况
            if (deltaBytes < 0 || timeSpan.TotalSeconds <= 0)
            {
                _lastWrittenBytes = writtenBytes;
                _lastMeasureTime = now;
                return;
            }

            var speedKb = deltaBytes / timeSpan.TotalSeconds / 1024.0; // KB/s
            var blockKb = deltaBytes / 1024.0; // KB

            // 确保值不为负数
            var speedValue = Math.Max(0, Math.Round(speedKb, 2));
            var blockValue = Math.Max(0, Math.Round(blockKb, 2));

            _isTransferring = speedValue > 0 || blockValue > 0;

            // 将数据添加到缓冲区，而不是直接更新图表
            lock (_bufferLock)
            {
                _dataBuffer.Enqueue((speedValue, blockValue));
                // 限制缓冲区大小，防止积压过多数据
                while (_dataBuffer.Count > 10)
                {
                    _dataBuffer.Dequeue();
                }
            }

            _lastWrittenBytes = writtenBytes;
            _lastMeasureTime = now;
        }

        private void AddPointInternal(double speedValue, double blockValue)
        {
            // 数据总是向左移动，新数据添加到最右边（末尾）
            ShiftLeft(_lineValues, speedValue);
            ShiftLeft(_barValues, blockValue);
            YAxes[0].MaxLimit = null;
            if (_lineValues.ToArray().Max(x => x.Value) is < 1)
            {
                YAxes[0].MaxLimit = 1;
            }
        }

        private static void ShiftLeft(ObservableCollection<ObservableValue> list, double newValue)
        {
            // 向左移动所有值（从索引0开始，每个值都被右边的值替换）
            for (var i = 0; i < list.Count - 1; i++)
            {
                // 使用平滑过渡而不是直接赋值，让动画更连贯
                var targetValue = list[i + 1].Value;
                list[i].Value = targetValue;
            }

            // 在最右边（末尾）添加新值
            list[^1].Value = newValue;
        }

        public void StartDecay(int milliseconds = 500, int intervalMs = 80)
        {
            _decayTotalTicks = milliseconds / intervalMs;
            _decayTicksLeft = _decayTotalTicks;
            _decayTimer?.Stop();

            _decayTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(intervalMs) };
            _decayTimer.Tick += (s, e) =>
            {
                if (_decayTicksLeft <= 0)
                {
                    _decayTimer?.Stop();
                    _isTransferring = false;

                    // 清空缓冲区并设置为零值
                    lock (_bufferLock)
                    {
                        _dataBuffer.Clear();
                        _currentData = (0, 0);
                        _previousData = (0, 0);
                    }
                    return;
                }

                // 使用指数衰减而不是线性衰减，让动画更自然
                var progress = (_decayTotalTicks - _decayTicksLeft) / (double)_decayTotalTicks;
                var easedProgress = 1 - Math.Pow(1 - progress, 3); // 三次方缓出
                var value = _lastSpeed * (1 - easedProgress);

                // 将衰减数据添加到缓冲区
                lock (_bufferLock)
                {
                    _dataBuffer.Enqueue((value, 0));
                }

                _decayTicksLeft--;
            };

            _decayTimer.Start();
        }

        public void SetProgressPercentage(int progress)
        {
            ProgressPercentage = progress;
        }

        // 添加重载方法支持double类型
        public void SetProgressPercentage(double progress)
        {
            ProgressPercentage = Math.Min(100.0, Math.Max(0.0, progress));
        }

        private static string ConvertSize(double sizeInKb)
        {
            switch (sizeInKb)
            {
                // 修正GB判断条件
                case >= 1024 * 1024 * 0.9:
                {
                    var sizeInGb = sizeInKb / 1024 / 1024;
                    return $"{sizeInGb:F1} GB";
                }
                // 修正MB判断条件
                case >= 1024 * 0.9:
                {
                    var sizeInMb = sizeInKb / 1024;
                    return $"{sizeInMb:F1} MB";
                }
                default:
                    return $"{sizeInKb:F1} KB";
            }
        }

        public void UpdateTransferProgress(long writtenBytes, long totalBytes)
        {
            var writtenKb = writtenBytes / 1024.0;
            var totalKb = totalBytes / 1024.0;

            var writtenStr = ConvertSize(writtenKb);
            var totalStr = ConvertSize(totalKb);

            TransferProgress = $"{writtenStr} / {totalStr}";
        }

        public void SetTransferLabel(string label)
        {
            TransferLabel = label;
        }

        public void StopUpdates()
        {
            _updateTimer?.Stop();
            _updateTimer = null;
            _decayTimer?.Stop();
            _decayTimer = null;
        }

        public void Dispose()
        {
            ApplicationThemeManager.Changed -= OnApplicationThemeChanged;
            GC.SuppressFinalize(this);
            StopUpdates();
            GC.SuppressFinalize(this);
        }

        // 添加终止处理
        ~SpeedChartViewModel()
        {
            StopUpdates();
        }
    }
}
